﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using PhiStore.Threading;

namespace PhiStore.ExampleCodes.PhiMovieStreamer
{
    public partial class MoviePlayer : Form
    {
        System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
        DateTime start;
        ulong imagesShowed = 0L;
        Channel<Bitmap> buffer;

        public MoviePlayer()
        {
            InitializeComponent();
            t.Interval = 20; //50 FPS, but is actually 32 FPS. Damn crappy inaccuracy
            t.Tick += new EventHandler(NewPicture);
        }

        delegate void refreshCallBack();

        public void RefreshMe()
        {
            
                if (buffer != null)
                {
                    try
                    {
                        Sheet.Image = buffer.Receive();
                        imagesShowed++;
                        Sheet.Refresh();
                    }
                    catch (PoisonException)
                    {
                        t.Stop();
                        TimeSpan ts = DateTime.Now.Subtract(start);
                        FPS.Text = (Convert.ToDouble(imagesShowed) / ts.TotalSeconds).ToString("N2") + " FPS";
                        buffer = null;
                    }
                }
        }

        public void RefreshMe(Object state)
        {
            RefreshMe();
        }

        void NewPicture(object sender, EventArgs e)
        {
            RefreshMe();
        }

        private void PlayButton_Click(object sender, EventArgs e)
        {
            imagesShowed = 0L;
            FPS.Text = "Running...";
            FPS.Refresh();
            IEnumerable<Bitmap> b = MovieGenerator.GenerateMovie();
            buffer = new Channel<Bitmap>(Convert.ToInt32(BufferSize.Value));
            MovieStreamer streamer = new MovieStreamer(buffer, b, Convert.ToInt64(Loops.Value));
            while (buffer.Count != buffer.Capacity)
            {
                Thread.Sleep(10); //filling buffer!
            }
            start = DateTime.Now;
            if (ShowMovie.Checked)
            {
                t.Start();
            }
            else
            {
                ReadTheDamnThing();
            }
        }

        private void ReadTheDamnThing()
        {
            try
            {
                while (true)
                {
                    buffer.Receive();
                    imagesShowed++;
                    Thread.Sleep(20); //50FPS
                }
            }
            catch (PoisonException)
            {
                TimeSpan ts = DateTime.Now.Subtract(start);
                FPS.Text = (Convert.ToDouble(imagesShowed) / ts.TotalSeconds).ToString("N2") + " FPS";
                buffer = null;
            }

        }

        private void MoviePlayer_FormClosing(object sender, FormClosingEventArgs e)
        {
            t.Stop();
        }

        private void Generate_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Generating the Movie takes roughly 40 minutes. Are you sure you wish to continue?", "Really Generate?", MessageBoxButtons.YesNo)
                == DialogResult.Yes)
            {
                MovieGenerator.Generate();
            }
        }

        private void PlayFromPhiStore_Click(object sender, EventArgs e)
        {
            imagesShowed = 0L;
            FPS.Text = "Running...";
            FPS.Refresh();
            IEnumerable<Bitmap> b = MovieGenerator.GenerateMovie(Convert.ToInt64(ChunkSize.Value), prefetch.Checked);
            buffer = new Channel<Bitmap>(Convert.ToInt32(BufferSize.Value));
            MovieStreamer streamer = new MovieStreamer(buffer, b, Convert.ToInt64(Loops.Value));
            while (buffer.Count != buffer.Capacity)
            {
                Thread.Sleep(10); //filling buffer!
            }
            start = DateTime.Now;
            if (ShowMovie.Checked)
            {
                t.Start();
            }
            else
            {
                ReadTheDamnThing();
            }
        }
    }
}
